package org.example.mq.mqsever.core;

/**
 * Created with IntelliJ IDEA.
 * Description:做渐进主义的改良派,不做完没注意的速成派
 * User: XALEXC
 * Date: 2025-04-28
 * Time: 15:40
 */

import java.io.Serializable;
import java.util.Arrays;
import java.util.UUID;

/**
 * 表示一个要传递的消息
 *  注意! 此处的Message 对象,是需要能够在网络上传输的,并且也需要能写入到文件中
 *  此处就需要针对 Message 进行序列化与反序列化
 *  此处使用标准库自带的序列化与反序列化操作
 *  此处不使用JSON方式,是因为JSON本质上是文本格式(里面放的也是文本类型的数据)
 *  而此处的 Message 里面存储的是 二进制 数据
 *  而需要被序列化的类需要实现一个特殊的接口
 */
public class Message implements Serializable {
    // 这两个属性是Message中最核心的部分
    private BasicProperties basicProperties =new BasicProperties();
    private byte[] body;
    // 下面的属性则是辅助用的属性
    // Message 后续会存储到文件中(如果持久化的话).
    // 一个文件会存储很多个消息. 如何找到某个消息在文件中的具体位置呢?
    // 使用下列两个偏移量来进行表示.[offsetBeg,offsetEnd)
    //这两个属性不需要被序列化保存到文件中2,此时消息一旦保存在文件之中,所在的位置就固定了,并不需要单独存储
    // 这两属性存在的目的,主要就是为了让内存中的 Message 对象,能够快速找到对应的硬盘上的 Message 的位置
    // 被 transient 修饰的属性,就不会被标准库进行序列化
    private transient long offsetBeg=0;// 消息数据的开头距离文件开头的位置偏移(字节)
    private transient long offsetEnd=0;// 消息数据的结尾距离文件开头的位置偏移(字节)

    // 使用这个属性表示该消息在文件中是否是有效消息.(逻辑删除)
    // 0x1 表示有效 0x0 表示无效.
    private byte isValid=0x1;

    // 创建一个工厂方法,让工厂方法帮我们封装一下创建 Message 对象的过程
    // 这个方法中创建的Message对象,会自动生产唯一的MessageId
    // 万一 routingKey 和 basicProperties 里的 routingKey 冲突,以外面的为主
    public static Message createMessageWithId(String routingKey,BasicProperties basicProperties,byte[] body){
        Message message=new Message();
        if (basicProperties!=null){
            message.basicProperties=basicProperties;
        }
        // 此处生成的MessageId以 M- 作为前缀
        message.setMessageId("M-"+UUID.randomUUID());
        message.basicProperties.setRoutingKey(routingKey);
        message.body=body;
        // 此处我们是吧 body 和 basicProperties 先设置出来.他两是 Message 的核心内容.
        // 而 offsetBeg,offsetEnd,isValid,则是消息持久化的时候才会用到.再把消息写入文件夹之前在进行设定
        // 此处只是在内存中创建一个Message对象.
        return message;
    }

    public String getMessageId(){
        return basicProperties.getMessageId();
    }

    public void setMessageId(String messageId){
        basicProperties.setMessageId(messageId);
    }

    public String getRoutingKey(){
        return basicProperties.getRoutingKey();
    }

    public void setRoutingKey(String routingKey){
        basicProperties.setRoutingKey(routingKey);
    }

    public int getDeliverMode(){
        return basicProperties.getDeliverMode();
    }
    public void setDeliverMode(int mode){
        basicProperties.setDeliverMode(mode);
    }

    public BasicProperties getBasicProperties() {
        return basicProperties;
    }

    public void setBasicProperties(BasicProperties basicProperties) {
        this.basicProperties = basicProperties;
    }

    public byte[] getBody() {
        return body;
    }

    public void setBody(byte[] body) {
        this.body = body;
    }

    public long getOffsetBeg() {
        return offsetBeg;
    }

    public void setOffsetBeg(long offsetBeg) {
        this.offsetBeg = offsetBeg;
    }

    public long getOffsetEnd() {
        return offsetEnd;
    }

    public void setOffsetEnd(long offsetEnd) {
        this.offsetEnd = offsetEnd;
    }

    public byte getIsValid() {
        return isValid;
    }

    public void setIsValid(byte isValid) {
        this.isValid = isValid;
    }

    @Override
    public String toString() {
        return "Message{" +
                "basicProperties=" + basicProperties +
                ", body=" + Arrays.toString(body) +
                ", offsetBeg=" + offsetBeg +
                ", offsetEnd=" + offsetEnd +
                ", isValid=" + isValid +
                '}';
    }
}
